#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
详细调试排列5序列LSTM增强模式预测问题
"""

import sys
import os
import torch
import numpy as np
from PyQt5.QtWidgets import QApplication

# 添加项目根目录到路径
project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, project_root)

def debug_sequence_lstm_detailed():
    """详细调试排列5序列LSTM增强模式预测问题"""
    print(" 详细调试排列5序列LSTM增强模式预测问题")
    print("=" * 60)
    
    try:
        from lottery_predictor_app import LotteryPredictorApp
        from algorithms.plw_sequence_lstm import PLWDataProcessor
        from algorithms.compatible_plw_lstm import load_compatible_plw_sequence_model
        
        # 创建应用
        if not QApplication.instance():
            app = QApplication(sys.argv)
        
        predictor = LotteryPredictorApp()
        
        print("📋 步骤1: 检查序列LSTM模型文件...")
        try:
            plw_model_path = os.path.join(project_root, 'scripts', 'plw', 'plw_sequence_lstm_model.pth')
            print(f"   模型文件路径: {plw_model_path}")
            print(f"   文件存在: {os.path.exists(plw_model_path)}")
            if os.path.exists(plw_model_path):
                size_mb = os.path.getsize(plw_model_path) / (1024*1024)
                print(f"   文件大小: {size_mb:.2f} MB")
        except Exception as e:
            print(f" 模型文件检查失败: {e}")
            return False
        
        print("\n📋 步骤2: 检查数据文件...")
        try:
            plw_data_file = os.path.join(project_root, 'scripts', 'plw', 'plw_history.csv')
            print(f"   数据文件路径: {plw_data_file}")
            print(f"   文件存在: {os.path.exists(plw_data_file)}")
            if os.path.exists(plw_data_file):
                size_mb = os.path.getsize(plw_data_file) / (1024*1024)
                print(f"   文件大小: {size_mb:.2f} MB")
        except Exception as e:
            print(f" 数据文件检查失败: {e}")
            return False
        
        print("\n📋 步骤3: 测试数据处理器...")
        try:
            processor = PLWDataProcessor(plw_data_file, window_size=10)
            recent_data = processor.get_recent_data()
            print(f"✅ 数据处理器测试成功")
            print(f"   最近数据形状: {recent_data.shape if recent_data is not None else 'None'}")
            if recent_data is not None:
                print(f"   数据类型: {type(recent_data)}")
                print(f"   数据示例: {recent_data[0, -1, :5].tolist()}")  # 显示最后时间步的5个数字
        except Exception as e:
            print(f" 数据处理器测试失败: {e}")
            import traceback
            traceback.print_exc()
            return False
        
        print("\n📋 步骤4: 测试兼容版模型加载...")
        try:
            device = torch.device('cpu')  # 强制使用CPU
            plw_model = load_compatible_plw_sequence_model(plw_model_path, device)
            print(f"✅ 兼容版模型加载成功")
            print(f"   模型类型: {type(plw_model)}")
            print(f"   模型设备: {next(plw_model.parameters()).device}")
        except Exception as e:
            print(f" 兼容版模型加载失败: {e}")
            import traceback
            traceback.print_exc()
            return False
        
        print("\n📋 步骤5: 测试输入数据准备...")
        try:
            if recent_data is not None:
                # 确保数据在正确的设备上
                recent_data = recent_data.to(device)
                print(f"   数据已移动到设备: {recent_data.device}")
                
                # 兼容版模型只需要前5个数字特征
                if recent_data.shape[-1] == 10:  # 如果是带区域转换特征的数据
                    input_data = recent_data[:, :, :5]  # 只取前5个数字特征
                    print(f"   已从10维特征中提取前5个数字特征")
                else:
                    input_data = recent_data
                    print(f"   使用原始数据作为输入")
                
                print(f"   输入数据形状: {input_data.shape}")
                print(f"   输入数据类型: {input_data.dtype}")
                print(f"   输入数据示例: {input_data[0, -1, :].tolist()}")
                
                # 确保输入数据是整数类型，并且在0-9范围内
                input_data = input_data.long()
                input_data = torch.clamp(input_data, 0, 9)
                print(f"   数据已转换为整数类型并限制在0-9范围内")
            else:
                print(" 无法获取最近数据")
                return False
        except Exception as e:
            print(f" 输入数据准备失败: {e}")
            import traceback
            traceback.print_exc()
            return False
        
        print("\n📋 步骤6: 测试模型预测...")
        try:
            num_predictions = 3
            predictions = []
            
            with torch.no_grad():
                for i in range(num_predictions):
                    print(f"   测试第{i+1}个预测...")
                    # 添加轻微噪声以产生多样性
                    noise_factor = 0.01 + i * 0.005
                    # 修复：先转换为float类型再添加噪声，然后转换回long类型
                    noisy_input = input_data.float() + torch.randn_like(input_data.float()) * noise_factor * 100
                    noisy_input = noisy_input.long()
                    # 确保噪声处理后的数据仍在0-9范围内
                    noisy_input = torch.clamp(noisy_input, 0, 9)
                    print(f"     噪声输入数据示例: {noisy_input[0, -1, :].tolist()}")
                    
                    # 调用模型预测
                    predictions_tensor, probabilities = plw_model.predict(noisy_input)
                    print(f"     预测张量形状: {predictions_tensor.shape}")
                    print(f"     预测张量类型: {type(predictions_tensor)}")
                    print(f"     概率张量: {probabilities is not None}")
                    if probabilities is not None:
                        print(f"     概率张量形状: {probabilities.shape}")
                    
                    predicted_numbers = predictions_tensor[0].cpu().numpy().tolist()
                    print(f"     预测数字: {predicted_numbers}")
                    
                    predictions.append({
                        'red': predicted_numbers,
                        'blue': [],  # 排列5没有蓝球
                        'confidence': float(torch.max(probabilities[0]).item()) if probabilities is not None else 0.8
                    })
            
            print(f"✅ 模型预测测试完成")
            print(f"   生成预测数量: {len(predictions)}")
            for i, pred in enumerate(predictions):
                print(f"   第{i+1}组: {pred}")
                
        except Exception as e:
            print(f" 模型预测测试失败: {e}")
            import traceback
            traceback.print_exc()
            return False
        
        print("\n📋 步骤7: 测试完整的序列LSTM增强模式预测...")
        try:
            predictions = predictor.get_enhanced_lstm_predictions("plw", 2)
            print(f"✅ 完整序列LSTM增强模式预测完成")
            print(f"   预测结果数量: {len(predictions)}")
            for i, pred in enumerate(predictions):
                print(f"   第{i+1}组: {pred}")
        except Exception as e:
            print(f" 完整序列LSTM增强模式预测失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
        return True
        
    except Exception as e:
        print(f" 详细调试失败: {e}")
        import traceback
        traceback.print_exc()
        return False

if __name__ == "__main__":
    success = debug_sequence_lstm_detailed()
    if success:
        print("\n🎉 详细调试完成！")
    else:
        print("\n❌ 详细调试失败！")